﻿@page "/Admin/Env"
@using System.Text
@using System.Text.Encodings.Web
@using System.Text.Json
@using System.Text.Unicode
@using iOSClub.Data
@using iOSClub.Data.DataModels
@using iOSClub.WebSite.Models
@using Microsoft.EntityFrameworkCore
@using Newtonsoft.Json
@using JsonSerializer = System.Text.Json.JsonSerializer
@inject IJSRuntime JS
@inject IDbContextFactory<iOSContext> DbFactory
@inject NavigationManager Nav

<PageTitle>其他数据 - iAdmin</PageTitle>

<InputFile id="fileInput" OnChange="@UploadFiles" hidden multiple/>

<PageView Style="min-height: 100%" ContextStyle="padding:10px;"
          FullScreen="true"
          OnDelete="@(() => Nav.NavigateTo("/Centre"))"
          Title="其他数据">
    <Extra>
        @if (Member.IsAdmin())
        {
            <Space Size="@("small")">
                <SpaceItem>
                    <Button Type="@ButtonType.Primary" OnClick="JsonDownload">下载所有数据</Button>
                </SpaceItem>
                <SpaceItem>
                    <Button Type="@ButtonType.Primary" Danger OnClick="RemoveAllData">删除所有数据</Button>
                </SpaceItem>
                <SpaceItem>
                    <Upload Name="files">
                        <label class="ant-btn" for="fileInput">上传Json数据</label>
                    </Upload>
                </SpaceItem>
            </Space>
        }
    </Extra>
    <Context>
        <Title Level="3">总述</Title>
        <Descriptions Bordered Column="@column">
            <DescriptionsItem Title="社员人数">@StudentsCount</DescriptionsItem>
            <DescriptionsItem Title="部员人数">@Staffs.Count</DescriptionsItem>
            <DescriptionsItem Title="社团项目数">@ProjectsCount</DescriptionsItem>
            <DescriptionsItem Title="任务数">@TasksCount</DescriptionsItem>
            <DescriptionsItem Title="社团各项资源数">@ResourcesCount</DescriptionsItem>
            <DescriptionsItem Title="部门数">@DepartmentsCount</DescriptionsItem>
            <DescriptionsItem Title="社员任务数">@TodosCount</DescriptionsItem>
        </Descriptions>
        <Divider/>
        <Title Level="3">部员列表</Title>
        <GridRow>
            @foreach (var staff in Staffs)
            {
                <GridCol Xs="12" Sm="12" Md="8" Lg="6" Xl="6" Xxl="6" class="card">
                    <span class="img" style="background-color: #7265e6;">
                        <span>@staff.Name.First()</span>
                    </span>
                    <h3>@staff.Name</h3>
                    <p style="color: #00000073;font-size: 0.9em;">@MemberModel.IdentityDictionary[staff.Identity]</p>
                </GridCol>
            }
        </GridRow>
        <br/>
    </Context>
</PageView>

@code
{
    [CascadingParameter] private MemberModel Member { get; set; } = new();

    private async Task UploadFiles(InputFileChangeEventArgs e)
    {
        var reader = new StreamReader(e.File.OpenReadStream());
        var result = await reader.ReadToEndAsync();
        reader.Dispose();
        if (string.IsNullOrEmpty(result)) return;
        await using var context = await DbFactory.CreateDbContextAsync();

        var allData = JsonConvert.DeserializeObject<AllDataModel>(result);

        if (allData == null) return;

        foreach (var student in allData.Students.Where(student => student.JoinTime.Year == 0))
        {
            student.JoinTime = DateTime.Parse("2023-10-18");
        }

        await context.Students.AddRangeAsync(allData.Students);
        await context.SaveChangesAsync();
        await context.Departments.AddRangeAsync(allData.Departments);
        await context.Staffs.AddRangeAsync(allData.Presidents.Where(staff => staff.Identity == "President"));
        await context.SaveChangesAsync();
        await context.Tasks.AddRangeAsync(allData.Tasks);
        await context.Projects.AddRangeAsync(allData.Projects);
        await context.Resources.AddRangeAsync(allData.Resources);
        await context.Todos.AddRangeAsync(allData.Todos);
        await context.Articles.AddRangeAsync(allData.Articles);
        await context.SaveChangesAsync();
    }

    private async Task JsonDownload()
    {
        var options = new JsonSerializerOptions
        {
            Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
        };
        await using var context = await DbFactory.CreateDbContextAsync();

        var Models = new AllDataModel
        {
            Students = await context.Students.ToListAsync(),
            Presidents = await context.Staffs.ToListAsync(),
            Tasks = await context.Tasks.ToListAsync(),
            Projects = await context.Projects.ToListAsync(),
            Resources = await context.Resources.ToListAsync(),
            Departments = await context.Departments.ToListAsync(),
            Todos = await context.Todos.ToListAsync(),
            Articles = await context.Articles.ToListAsync()
        };
        var jsonString = JsonSerializer.Serialize(Models, options);
        var data = Encoding.UTF8.GetBytes(jsonString);

        await JS.InvokeVoidAsync("jsSaveAsFile", "allData.json", Convert.ToBase64String(data));
    }

    private async Task RemoveAllData()
    {
        await using var context = await DbFactory.CreateDbContextAsync();
        await context.Projects.ExecuteDeleteAsync();
        await context.Resources.ExecuteDeleteAsync();
        context.Staffs.RemoveRange(context.Staffs.Where(x => x.Identity != "Founder"));
        await context.Students.ExecuteDeleteAsync();
        await context.Tasks.ExecuteDeleteAsync();
        await context.SaveChangesAsync();
    }

    private int StudentsCount { get; set; }
    private int ProjectsCount { get; set; }
    private int TasksCount { get; set; }
    private int ResourcesCount { get; set; }
    private int DepartmentsCount { get; set; }
    private int TodosCount { get; set; }
    private List<StaffModel> Staffs { get; set; } = [];

    private readonly Dictionary<string, int> column = new()
    {
        { "xxl", 3 },
        { "xl", 3 },
        { "lg", 2 },
        { "md", 2 },
        { "sm", 1 },
        { "xs", 1 }
    };

    protected override async Task OnInitializedAsync()
    {
        await using var context = await DbFactory.CreateDbContextAsync();
        StudentsCount = await context.Students.CountAsync();
        Staffs = await context.Staffs.ToListAsync();
        ProjectsCount = await context.Projects.CountAsync();
        TasksCount = await context.Tasks.CountAsync();
        ResourcesCount = await context.Resources.CountAsync();
        DepartmentsCount = await context.Departments.CountAsync();
        TodosCount = await context.Todos.CountAsync();
    }
}

<style>
    .card {
        transition: .2s;
        cursor: pointer;
        border-radius: 10px;
        align-items: center;
        border: 1px solid transparent;
        display: flex;
        flex-direction: column;
    }

    .img {
        width: 2.6rem;
        height: 2.6rem;
        margin: .5rem 0;
        border-radius: 4rem;
        align-items: center;
        justify-items: center;
        display: flex;
        flex-direction: column;
        vertical-align: middle;
    }

    .img span {
        display: grid;
        height: 100%;
        align-items: center;
        justify-items: center;
        color: #ffffff;
    }

    .card:hover {
        border-color: #1890ff;
    }

    @@media screen and (max-width: 767px) {
        .card {
            flex: 0 0 25%;
            max-width: 25%;
        }
    }

</style>